package com.ccteam.shared.domain.home.recommend

import android.content.Context
import android.support.v4.media.MediaMetadataCompat
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.common.utils.MediaIDHelper
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.model.Resource
import com.ccteam.model.album.AlbumSimplifyVO
import com.ccteam.model.banner.BannerVO
import com.ccteam.model.music.BITRATE_NO
import com.ccteam.model.music.MusicVO
import com.ccteam.model.playlistsheet.PlaylistSheetVO
import com.ccteam.shared.data.home.OnlineMusicHomeRepository
import com.ccteam.shared.domain.FlowUseCase
import com.ccteam.shared.result.home.OnlineMusicBanner
import com.ccteam.shared.result.home.OnlineMusicHomeInnerSmallItem
import com.ccteam.shared.utils.*
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/5/5
 *
 * 首页推荐Domain层
 */
class HomeRecommendDataUseCase @Inject constructor(
    @ApplicationContext private val context: Context,
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow,
    private val homeRepository: OnlineMusicHomeRepository
): FlowUseCase<Nothing?,List<Recommend>>(Dispatchers.IO) {

    override fun execute(parameters: Nothing?): Flow<Resource<List<Recommend>>> {
        return merge(homeRepository.getBanner(),
            homeRepository.getNewAlbumRecommend(),
            homeRepository.getNewMusicRecommend(),
            homeRepository.getHotMusicRecommend(),
            homeRepository.getHotPlaylistSheetRecommend()).map { result ->

            // 将新音乐加入到BrowseTree中
            val newMusic = result.data?.filterIsInstance<MusicVO>()
            if(!newMusic.isNullOrEmpty()){
                addMusicToBrowseTree(MediaIDHelper.ONLINE_MEDIA_NEW_MUSIC,newMusic)
            }
            val hotMusic = result.data?.filterIsInstance<OnlineMusicHomeRepository.HotMusicData>()?.map {
                it.music
            }
            if(!hotMusic.isNullOrEmpty()){
                addMusicToBrowseTree(MediaIDHelper.ONLINE_MEDIA_HOT_MUSIC,hotMusic)
            }

            val data = result.data?.map {
                when(it){
                    is BannerVO ->{
                        Recommend.RecommendBanner(OnlineMusicBanner(it.url, it.itemId, it.type))
                    }
                    is AlbumSimplifyVO ->{
                        Recommend.RecommendNewAlbum(
                            OnlineMusicHomeInnerSmallItem(
                                it.id,
                                it.imgUrl + ALBUM_QUALITY,
                                it.name,
                                it.artistName,
                                false,
                                NO_PLAYING
                            )
                        )
                    }
                    is MusicVO ->{
                        Recommend.RecommendNewMusic(
                            OnlineMusicHomeInnerSmallItem(
                                it.id,
                                it.imgUrl + ALBUM_QUALITY,
                                it.name,
                                it.albumName,
                                !it.url.isNullOrEmpty(),
                                musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(it.id),
                                parentId = MediaIDHelper.ONLINE_MEDIA_NEW_MUSIC
                            )
                        )
                    }
                    is PlaylistSheetVO -> {
                        Recommend.RecommendHotPlaylistSheet(
                            OnlineMusicHomeInnerSmallItem(
                                it.id,
                                it.imgUrl + PHOTO_QUALITY,
                                it.playlistName,
                                EMPTY_STRING,
                                false,
                                NO_PLAYING
                            )
                        )
                    }
                    is OnlineMusicHomeRepository.HotMusicData ->{
                        Recommend.RecommendHotMusic(
                            OnlineMusicHomeInnerSmallItem(
                                it.music.id,
                                it.music.imgUrl + ALBUM_QUALITY,
                                it.music.name,
                                EMPTY_STRING,
                                !it.music.url.isNullOrEmpty(),
                                musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(it.music.id),
                                parentId = MediaIDHelper.ONLINE_MEDIA_HOT_MUSIC
                            )
                        )
                    }
                    else ->{
                        Recommend.RecommendNewAlbum(
                            OnlineMusicHomeInnerSmallItem(
                                "",
                                "",
                                "",
                                "",
                                false,
                                NO_PLAYING
                            )
                        )
                    }
                }
            } ?: emptyList()
            when(result){
                is Resource.Success ->{
                    Resource.Success(data)
                }
                is Resource.Loading ->{
                    Resource.Loading(data)
                }
                is Resource.Error ->{
                    Resource.Error(result.errorCode,result.message ?: "未知错误")
                }
            }
        }
    }

    private fun addMusicToBrowseTree(parentId: String,musicList: List<MusicVO>){
        /**
         * 将音乐信息加入到browseTree中以便播放
         */
        val items  = mutableListOf<MediaMetadataCompat>()
        musicList.forEach { music ->
            // 如果当前音乐没有音源，则不加入到其中
            if(music.maxBitrate == BITRATE_NO || music.url.isNullOrEmpty()){
                return@forEach
            }
            items.add(
                MediaMetadataCompat.Builder().apply {
                    id = music.id
                    duration = music.duration
                    title = music.name
                    displayTitle = music.name
                    album = music.albumName
                    displaySubtitle = music.albumName
                    displayDescription = music.artists
                    artist = music.artists
                    albumId = music.albumId
                    trackNumber = music.track.toLong()
                    mediaUri = music.url
                    albumArtUri = music.imgUrl + ALBUM_QUALITY
                    displayIconUri = music.imgUrl + ALBUM_QUALITY
                }.build()
            )
        }
        musicServiceConnectionFlow.addOnlineMusicItems(
            parentId = parentId,
            items = items
        )
    }
}


sealed class Recommend{
    class RecommendBanner(val item: OnlineMusicBanner): Recommend()
    class RecommendNewMusic(val item: OnlineMusicHomeInnerSmallItem): Recommend()
    class RecommendNewAlbum(val item: OnlineMusicHomeInnerSmallItem): Recommend()
    class RecommendHotMusic(val item: OnlineMusicHomeInnerSmallItem): Recommend()
    class RecommendHotPlaylistSheet(val item: OnlineMusicHomeInnerSmallItem): Recommend()
}